home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Spanish Scene 1
/
SpanishScene1.iso
/
spanish pack n°1 by llfb
/
revistas
/
fanzine
/
fanzine01.dms
/
fanzine01.adf
/
40
< prev
next >
Wrap
Text File
|
1977-12-31
|
10KB
|
277 lines
----------------------------------------------------------------------------
T E C N I C A S D E I N T E L I G E N C I A A R T I F I C I A L
* INTRODUCCION A LA TEORIA DE GRAFOS *
----------------------------------------------------------------------------
Curso escrito por Warlord
Mi intención con este semi-cursillo es hacer llegar a todos,de una forma
sencilla y amena varias técnicas relacionadas con la Int. Artificial, poco
utilizadas generalmente por los programadores. Intentaré dar en cada caso,
algoritmos en C de cada una de estas técnicas. Si no sabéis C, os remito
al curso de esta revista. ¡Por cierto!, algunos de estos pseudocódigos en
C, no he probado si funcionan correctamente. Quiero decir, que el
algoritmo está bien escrito, pero el programa en C puede tener algún error
en el tipo de variables y cosas así, que se pueden arreglar fácilmente.
El problema de grafos que aquí os planteo es tan sólo una breve, muy breve
explicación sobre este apasionante mundo: Grafos, programación dinámica ...
temas que escapan al conocimiento del usuario medio.Posiblemente, este tema
no interese a mucha gente,pero me contentaría con que interesara a una sóla
persona.Podéis dirigir vuestras cartas al apdo 232,San Fernando 11100,Cádiz
Mi contacto con la IA (inteligencia artificial), fué ya hace mucho tiempo
cuando comencé a desarrollar un juego de estrategia. El problema que se me
planteaba, era el siguiente:
Disponía de un mapa de Europa con aproximadamente unos 30 países. Cada
país era controlado de forma independiente por el ordenador, a excepción
de España, que lo controlaba el jugador. Con el paso del tiempo, un país
conquistaba a otros vecinos. Se planteaba entonces el problema de tener
inactivos a los ejércitos en un país. El ordenador debía entonces detectar
cuando debía mover ejércitos de un país a otro, y como moverlos de una
forma óptima, de manera que pasaran por el menor número de países posible,
pues esto supondría un mayor coste. La solución lógica a estos problemas
viene a través de los grafos.
¿Pero qué es un grafo?
Un grafo es un conjunto formado por unos puntos llamados nodos,y líneas
que comunican un nodo con otro, llamados caminos.
O------O--O O = Vértices
/ / / -,/ = Caminos de un vértice a otro
O------O--/
UN BONITO EJEMPLO:
-----------------
¿Quién no ha visto en algún pasatiempo eso de recorrer un dibujo sin reco-
rrer dos veces la misma linea?. Si, por ejemplo:
O
/ \ Es el típico dibujo de la casita. ¿Como recorrer
/ \ todo el dibujo sin pasar dos veces por la misma
O¯¯¯¯¯¯¯O línea?. Este problema, es uno típico de grafos. Los
| \ / | vértices son los "O" y las líneas los arcos.
| \ / |
| / |
| / \ |
| / \ |
|/ \|
O¯¯¯¯¯¯¯O
Por cierto, para aquellos que les interese: para saber si un problema de
este tipo tiene solución, hay que fijarse en los vértices. Miramos las
líneas (arcos) que llegan a cada uno, y apuntamos aquellos en que esta
cantidad de líneas es impar.
En nuestro ejemplo: Del vértice superior llegan dos líneas (Par)
Como es par, no nos vale para nada.
En los dos siguientes, llegan 4 líneas. También par
En los dos inferiores, llegan ¡3 líneas!, ¡Impar!. Tenemos dos vertices
impares.
Una vez hecho esto, puede ocurrir:
- Que no haya ningún vértice "con líneas impares". Si esto ocurre, el pro-
blema se puede hacer empezando desde cualquier vértice y acabando en cual-
quier otro
- Que haya exactamente 2 vértices " con líneas impares ", como en nuestro
ejemplo. El problema tiene solución. Pero hay que empezar en uno de estos
vértices y necesariamente acabar en el otro. En nuestro ejemplo, habría
que empezar en uno de los dos de abajo y acabar en el otro
- Que no pase nada de lo de antes. El problema no tiene solución.
¿Interesante, verdad?
ALGUNOS EJEMPLOS MAS SERIOS:
---------------------------
Supongamos que deseamos ir desde Cádiz hasta Barcelona. Las rutas son
múltiples y variadas. Nuestra intención seria viajar, haciendo el mínimo
número de kilómetros.
La representación y solución de este problema es bien fácil mediante
grafos. Representamos Cádiz, como el vértice 1. A las ciudades entre
ella y Barcelona, por donde pasen carreteras les vamos dando el nombre
de otros vértices: 2,3,4.... hasta llegar a Barcelona.Unimos cada ciudad
por el camino correspondiente. La distancia de una ciudad a otra, sería
el costo para trasladarse de una ciudad a otra. Asi, seriá:
4 (linares)
O
\ O 3 (Córdoba)
\ / Costo=130 Km
|/
O Vertice 2 (Sevilla)
|
| Costo=153 Km
|
O Vertice 1 (Cádiz)
y así sucesivamente. ¿Fácil no?
Supongamos entonces que Cádiz es el vértice 1,y Barcelona el 45.
Definimos una tabla T(45,45),donde T(i,j) va a significar la distancia
del vértice (ciudad en este caso) i a la j.
Así por ejemplo: T(1,1)=0 distancia de Cadiz a Cádiz=0
T(1,2)=T(2,1)=153 (distancia de Cádiz a Sevilla)
Nuestra intención es hallar el mínimo de estas distancias
Si por ejemplo Madrid fuera el vértice 13, T(1,13) no debería existir
pues no hay comunicación directa entre ambas ciudades.Es decir,si hay de
Cadiz a Sevilla,de Sevilla a Córdoba y de Córdoba a Madrid.Pero no direc-
tamente.Así,definimos todas estas como un número grande,de manera que en
la solución,esta carretera no aparezca.
Por ejemplo,T(1,13)=99999999999,de esta forma este camino no aparecería
en la solución,pues si T(1,13) fuese 0,aparecéria seguro en la solución,
lo cual sería contraproducente.
RESOLUCION DE GRAFOS:
--------------------
El siguiente pseudocódigo resuelve este problema.
Supongamos que queremos hallar el camino más corto del vértice 1 al N
Definimos f(i)=camino más corto del vertice i al N
La solución deseada sería entonces f(1)
main()
{
for (i=2,i<=N,i++) v(i)=t[1,i];
T={2,....N}
While (T!=Ø){ (Ø=conjunto vacío)
v[i]=min(v[j],j en T);
T=T-{i}
while (j en T) v[j]=min(v[j],v[i]+t[i,j]);
}
}
Una vez finalizado,obtenemos que v[i]=f(i),con lo cual v[1] sería la
solución
Un ejemplo concreto:
2 5
O------------------------O--/------------O 7
/ \ / / \
/ \ 4 / / 8 \
1 O ----O--------------/--- O------------ O 9
\ |_____________________/| /
\ | | /
\ --------------------|/ /
3 O--------------------------O------------
6
(perdonar el dibujo,es difícil hacerlo mejor)
Llamando como antes t(i,j)=distancia del vértice i al j:
t(1,2)=1 t(1,3)=2 t(3,6)=4 t(4,5)=4 t(4,6)=3 t(5,7)=7
t(2,5)=12 t(3,4)=3 t(2,4)=6 t(4,8)=7 t(4,7)=15 t(6,8)=7
t(6,9)=15 t(7,9)=4 t(8,9)=10
El resto no existe (ie,se les dá un valor alto)
Os recomiendo lo dibujéis en un papel
¿Cómo se resuelve?
En el programa anterior,la línea clave es:
while (j en T) v[j]=min(v[j],v[i]+t[i,j]);
f(i)=camino más corto de i a 9
Según el programa anterior, f(i) es pues:
f(i)=min (f(j)+t[i,j])
La idea es empezar con f(9):
f(9)=f(j)+t[j,9] ,donde j son los vértices (nodos) antecesores de 9:
f(9)=min (f(7)+3,f(8)+10,f(6)+15)
Necesitamos ir hallando ahora f(7),f(8) y f(6) recurrentemente:
f(7)=min(f(5)+7,f(5)+15)
f(8)=min(f(4)+7,f(6)+7)
f(6)=min(f(4)+3,f(3)+4)
Ahora necesitamos f(4),f(5)....Aplicamos de nuevo lo mismo y así llega-
mos a f(1).Una vez conocido f(1),conocer el resto es inmediato.
Si lo hacéis veréis que la menor distancia a recorrer es a través de los
nodos:
1 --> 3 --> 4 --> 5 --> 7 --> 9
Desde luego es una forma interesante de resolver un grafo. Sin embargo,
no sería aplicable al primer ejemplo, el del mapa de Europa.Este algoritmo
nos ha dicho el algoritmo más corto del primer nodo del grafo a otro nodo
cualquiera. Pero en el ejemplo del juego de estrategia nos interesa el coste
del camino más corto entre cualquier par de países, es decir, entre
cualesquiear par de nodos.
Para resolver este problema podemos utilizar el algoritmo de Floyd:
ALGORITMO DE FLOYD:
------------------
Para ello dimensionaremos una matriz L, de tamaño NxN (N=Número de vérti-
ces o nodos),y cuyos elementos van a tener el minimo coste entre todos los
costes de los caminos que unen los nodos i,j.El algoritmo no puede ser más
sencillo. He aquí el pseudocódigo:
/* Asignación de variables*/
for (i=1,i<=N,i++);
{
for (j=1,j<=N,j++);
{
l(i,j)= | longitud del camino que une los nodos (i,j)
| 99999999999 en otro caso (de que no exista)
}
}
/* Programa principal*/
for (i=1,i<=N,i++);
{
for (j=1,j<=N,j++);
{
for (k=1,k<=N,k++);
{
l(i,j)=min(l(i,j),l(i,k)+l(k,j);
}
}
}
Al final cada elemento l(i,j) tendrá el mínimo costo(es decir,la mínima
longitud) de los caminos que unen i con j.Así pues, si queremos ir del
país 4 al 10, la mínima distancia a cubrir se encuentra en l(4,10).
Por hoy,ya está bien. Espero que estas rutinas os sean de utilidad,y si
es así, espero vuestras cartas y comentarios.Hasta la próxima...